<?php
/**
 * This class represents 'bed' table.
 *
 * @package core.ordo 
 * @author pktquynh
 * @version $Id:$
 * @copyright 2009 LHV Company
 */
class Bed extends ORDataObject {
    
    var $bed_id    = '';   
    var $code       = '';
    var $max_patients = '';
    var $price = '';
    var $insurance_price = '';
    var $enum_price_type = '';
    var $deleted = '';
    var $room_id = '';
    
    var $_table         = 'bed';
    var $_internalName  = 'Bed';
    var $_key       = 'bed_id';
    
    public function Bed($id = 0)  {
        //call the parent constructor so we have a _db to work with
        parent::ORDataObject();     
    }
    
    /**
     * Check whether or not bed code exists in a specific room and department.
     * @param int $deptId The id of department
     * @param int $roomId The id of room
     * @param string $code The bed code
     * @return false|id false if bed code is not existed, otherwise return bed id 
     */
    public function checkExisted($deptId, $roomId, $code) {
        $ds = new Datasource_sql();
        $sql = array (
            'cols'    => "bed_id",
            'from'    => $this->_table . " b"
                         . " INNER JOIN room r ON b.room_id = r.room_id "
                         . " INNER JOIN department d ON r.department_id = d.department_id", 
            'where'   => "b.room_id = " . $roomId 
                         . " AND d.department_id = " . $deptId
                         . " AND code = '" . $code . "'", 
            'orderby' => "code");
                         
        $ds->setup($this->_db, $sql);
        $beds = $ds->toArray();
        if (count($beds) == 0) {
        	return false;
        } else {
        	return $beds[0]['bed_id'];
        }
    }
    
    /**
     * Create one bed in database.
     * @param $bed contains information of bed eg. room, code ...
     * @return int The identifier of created bed. 
     */
    public function addBed($bed) {
    	$data = array ('code'             => $bed['bedCode'],
                       'max_patients'     => $bed['maxPatients'],
    	               'price'            => $bed['price'],
    	               'insurance_price'  => $bed['price'],
    	               'enum_price_type'  => $bed['priceType'],
    	               'room_id'          => $bed['roomId']);      
        $this->populateArray($data);        
        $this->persist();           
        return $this->bed_id;
    }
    
    /**
     * Update a specific bed.
     * @param array $bed contains bed information to update
     */
    public function updateBed($bed) {
    	$data = array ('code'             => $bed['bedCode'],
                       'max_patients'     => $bed['maxPatients'],
                       'price'            => $bed['price'],
                       'insurance_price'  => $bed['price'],
                       'enum_price_type'  => $bed['priceType'],
                       'room_id'          => $bed['roomId']);
    	$this->setup($bed['bedId']);
    	$this->populateArray($data);
    	$this->persist();
    }
    
    /**
     * Get all undeleted beds of some department and some room.
     * If $deptId and $roomId are null, get all beds of all rooms in each department.
     * If $roomId is null, get all beds of all rooms in the specific department.
     * @param int $deptId id of the specific department
     * @param int $roomId id of the specific room 
     * @return list of beds
     */
    public function getListOfBeds($deptId, $roomId) {
    	$field    =   L10nHelper::changeField(L10nHelper::getLocale(), 'name');
        
    	$ds = new Datasource_sql();
    	// ignore default bed
    	$where = "bed_id != 1";
    	if ($deptId != 'empty' && $roomId == 'empty') {
    	    $where = $where . " AND d.department_id = " . $deptId;
    	    
    	} else if ($deptId != 'empty' && $roomId != 'empty') {
    		$where = $where 
    		       . " AND d.department_id = " . $deptId 
    		       . " AND b.room_id = " . $roomId;
    	}
    	$sql = array (
            'cols'    => "d.department_id, d.$field as department_name, r.room_id, r.$field as room_name," 
                        . "bed_id, code, max_patients, price, b.enum_price_type as price_type, b.deleted",
            'from'    => $this->_table . " b"
                         . " LEFT JOIN room r ON b.room_id = r.room_id "
                         . " LEFT JOIN department d ON r.department_id = d.department_id "                         ,
            'where'   => $where, 
            'orderby' => "department_name, room_name, code");
                         
        $ds->setup($this->_db, $sql);
        $result = $ds->toArray();        
        return $result;
    }
    
    /**
     * Get information of a specific bed.
     * @param $bedId The identifier of bed
     * @return false|array return false if the bed is not found
     */
    public function getBed($bedId) {
    	$field    =   L10nHelper::changeField(L10nHelper::getLocale(), 'name');
        
        $ds = new Datasource_sql();
        $sql = array (
            'cols'    => "d.department_id, d.$field as department_name, r.room_id, r.$field as room_name," 
                        . "bed_id, code, max_patients, price, b.enum_price_type as price_type, b.deleted",
            'from'    => $this->_table . " b"
                         . " LEFT JOIN room r ON b.room_id = r.room_id "
                         . " LEFT JOIN department d ON r.department_id = d.department_id ",
            'where'   => " bed_id = " . $bedId, 
            'orderby' => "department_name, room_name, code");

        $ds->setup($this->_db, $sql);
        $result = $ds->toArray();        
        if (empty($result)) {
        	return false;
        } else {
        	return $result[0];
        }
    }
    
    /**
     * Mark a specific bed as deleted in database.
     * @param $bedId The id of bed to delete
     */
    public function removeOrUndoBed($bedId, $action) {
    	$sql = '';
    	if ($action == 'remove') {
    	    $sql = "UPDATE bed SET deleted = 1 WHERE bed_id = '$bedId'";
    	} else if ($action == 'undo') {
    		$sql = "UPDATE bed SET deleted = 0 WHERE bed_id = '$bedId'";
    	}        
        $this->_execute($sql);
    }
    
    /**
     * Get all rooms which has at least one bed in the specific department.
     * 
     * @param int $deptId The id of department
     */
    public function getRoomsAtLeastBed($deptId) {
        $field    =   L10nHelper::changeField(L10nHelper::getLocale(), 'name');
        
        $ds = new Datasource_sql();
        $sql = array (
            'cols'    => "distinct r.room_id, r.$field as room_name",
            'from'    => "room r "
                         . " INNER JOIN bed b ON r.room_id = b.room_id "
                         . " LEFT JOIN department d ON r.department_id = d.department_id ",
            'where'   => " r.department_id = " . $deptId,
            'orderby' => "room_name");

        $ds->setup($this->_db, $sql);
        return $ds->toArray();
    }
    
    /**
     * Get all rooms in the specific department with further information of beds.
     * 
     * @param int $deptId The id of department
     */
    public function getRoomsWithAvailableBeds($roomIds) {                
        $ds = new Datasource_sql();
        $sql = array (
            'cols'    => "b.room_id, b.bed_id, b.max_patients, SUM(if(pb.current=1, 1, 0)) as patients",
            'from'    => "bed b LEFT JOIN patient_bed pb ON b.bed_id = pb.bed_id",
            'where'   => " b.room_id IN ($roomIds) "
                       . " AND b.bed_id != 1"
                       . " AND b.deleted = 0",
            'groupby' => "b.room_id, b.bed_id");

        $ds->setup($this->_db, $sql);
        return $ds->toArray();
    }
    
    /**
     * Get available beds of the specific room. Search table 'bed' with criteria 'room_id' and this bed_id is 
     * not in (table 'patient_bed' with 'current=true'); and number of patients in bed is not greater than 
     * max_patients.
     */
    public function getAvailableBedsOfRoom($roomId) {
    	$ds = new Datasource_sql();
        $sql = array (
            'cols'    => "distinct bed_id, code",
            'from'    => "bed",
            'where'   => " room_id = '" . $roomId . "'"
                       . " AND bed_id != 1"
                       . " AND deleted = 0"
                       . " AND (bed_id, max_patients) NOT IN"
                       . "    (SELECT bed_id, count(bed_id)" 
                       . "     FROM patient_bed"
                       . "     WHERE current = 1"
                       . "     GROUP BY bed_id)",
            'orderby' => "code");

        $ds->setup($this->_db, $sql);
        return $ds->toArray();
    }
    
    /**
     * Get bed information and current number of patients for all beds of a specific room.
     * @param int $roomId The id of room
     * @return array contains (bed_id, code, max_patients and patients) of beds
     */
    public function getNumberOfPatientsForBed($roomId) {
    	$ds = new Datasource_sql();
        $sql = array (
            'cols'    => "b.bed_id, b.code, b.max_patients, SUM(IF(pb.current=1, 1, 0)) as patients",
            'from'    => "bed b LEFT JOIN patient_bed pb ON b.bed_id = pb.bed_id",
            'where'   => " b.room_id = '" . $roomId . "'"
                       . " AND b.bed_id != 1"
                       . " AND b.deleted = 0",
            'groupby' => "b.bed_id, b.code",         
            'orderby' => "b.code");

        $ds->setup($this->_db, $sql);
        return $ds->toArray();
    }
    
}
?>